home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
basic
/
ms2id_tb.zip
/
MSTOID.ASM
next >
Wrap
Assembly Source File
|
1987-10-06
|
5KB
|
132 lines
page ,132
;
; MSTOID.ASM
;
; Turbo Basic $INLINE procedure for converting from
; Microsoft double precision format to Turbo's IEEE
; long real format
;
; declaration format:
;
; SUB MSTOID INLINE
; $INLINE "MSTOID.BIN"
; END SUB
;
; calling example:
;
; FIELD #1,8 AS MSNUMBER$ ' Microsoft format in file
; MS# = CVD(MSNUMBER$) ' do NOT use CVMD() here !!!
; CALL MSTOID(MS#,I#) ' converts to Turbo Basic format
;
; where MS# is a double precision number in Microsoft floating
; point format (get with 'CVD', not 'CVMD') and I# is a variable
; which will receive the converted IEEE long real result.
; You may use the same variable for MS# and I#.
;
; algorithm used:
;
; 1) Pointers to each variable are placed in DS:SI and ES:DI. Each
; variable is 8 bytes long and the bytes will be processed from
; high addresses to low addresses (most significant bits first).
;
; 2) Considering each number as a 64 bit field (bit 63 = most
; significant), the formats are
;
; Microsoft: Bits 63-56 = 8 bit exponent, biased 129
; Bit 55 = mantissa sign bit
; Bits 54-0 = 55 bit normalized mantissa
;
; IEEE: Bit 63 = mantissa sign bit
; Bits 62-52 = 11 bit exponent, biased 1023
; Bits 51-0 = 52 bit normalized mantissa
;
; 3) Zero is handled as a special case, in which all bits are
; set to zero. Although IEEE allows both positive and negative
; zero, the Microsoft format uses only a positive zero.
;
; 4) The exponent is extracted from the Microsoft number and the
; bias is adjusted to IEEE. The Microsoft sign bit is placed
; in front of the exponent and the combination is placed in BX.
; This is now the first 12 bits (63-52). To fill out 2 bytes,
; the first four Microsoft mantissa bits are inserted, and BX
; is stored as the first 16 IEEE bits.
;
; 5) There now remains 48 IEEE mantissa bits to be filled from the
; most significant 48 Microsoft mantissa bits. These are moved
; in a loop which performs a 3 bit right shift. The 3 least
; significant Microsoft mantissa bits are lost.
;
; 6) The decimal precision of the Microsoft format is
; log(2^56) = 16.9 digits, while the decimal precision of
; the IEEE format is log(2^53) = 16.0 digits. This loss of
; precision is a trade-off for the extended exponent range
; available with the IEEE format
;
MSBIAS equ 129 ; Microsoft exponent bias
IBIAS equ 1023 ; IEEE exponent bias
code segment
assume cs:code
org 0100h ; need .COM format for $INLINE
start:
push bp ; establish stack frame addressing
mov bp,sp
push ds ; save segment registers
push es
lds si,[bp+10] ; get pointer to MS# in DS:SI
les di,[bp+6] ; get pointer to I# ES:DI
cmp word ptr [si+6],0 ; check for input value of zero
jne notzero ; no, need to convert
xor al,al ; yes, zero out destination
mov cx,8
cld
rep stosb
jmp done
notzero:
xor ax,ax
mov al,byte ptr [si+7] ; get exponent byte
add ax,(IBIAS - MSBIAS) ; convert bias
shl ax,1 ; shift into position
shl ax,1
shl ax,1
shl ax,1
mov bh,byte ptr [si+6] ; get byte with sign bit
and bx,8000h ; mask off sign bit
or bx,ax ; add in exponent
mov al,byte ptr [si+6] ; get first 4 mantissa bits
ror ax,1 ; 3 lower bits to AH higher bits
ror ax,1 ; and first 4 mantissa bits
ror ax,1 ; to lower AL bits
and al,0Fh ; mask off lower 4 bits
or bl,al ; place with BX
mov word ptr es:[di+6],bx ; store exponent, sign, 4 mant. bits
mov bx,6 ; last byte moved
next:
dec bx
ror ax,1 ; move upper 3 AH bits
ror ax,1 ; to lower 3 bits
ror ax,1
ror ax,1
ror ax,1
mov al,[bx+si] ; fetch next source byte
ror ax,1 ; rotate 3 bits right
ror ax,1 ; to build byte of 3 + 5 bits
ror ax,1
mov es:[bx+di],al
cmp bx,0 ; are we done?
jg next ; yes
done:
pop es ; restore registers
pop ds
pop bp
; Turbo handles the RET
code ends
end start